/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package huetari_48;

import java.io.IOException;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdom2.*;
import org.jdom2.input.*;
import org.jdom2.xpath.XPath;
/**
 * Se encarga de realizar el analsis sintactico sobre las fichas que se van colocando, la sintaxis la valida
 * utilizando el XML sintaxisFichas
 * @author kenneth
 */
public class AnalizadorSintactico implements IConstantes
{
    private Element NodoTem;
    private Document documento;
    private Vector<String[]> posicionesValidas = new Vector();
    private boolean posValidaUp=false;
    private boolean posValidaDown=false;
    private boolean posValidaIzq=false;
    private boolean posValidaDer=false;
    private boolean cumpleRequerimientos=false;
    private int posFilaEspecial;
    private int posColumEspecial;
    private String[] requerimientos={""};
    
    /*
     * El constructor carga el archivo XML esto para que cuando se cree la instancia de la clase este cargado el 
     * archivo
     */
    public AnalizadorSintactico() throws JDOMException, IOException
    {
        SAXBuilder builder=new SAXBuilder(false);
        documento=builder.build("src/Files/sintaxisFichas.xml");
    }
    
    /*
     * Metodo encargado de obtener las posiciones validas que puede tener una ficha, lo obtiene desde el XML, las 
     * posiciones validas son arriba, abajo, izquierda y derecha, una vez que las carga del XML las mete
     * en un String[](pues puede exitis mas de una ficha que se puede colocar) y luego ese String[] en un vector 
     * para asi hacer mas eficiente la validacion, con ayuda del metodo validarSintaxis analiza cada una de las posiciones
     * retornando un boolean, al final se retorna un boolean entre todas las posiciones.
     */
    public boolean validarSintaxisDePosicion(String Matriz[][],int fila, int colum, String nombreFicha) throws JDOMException
    {
        posValidaUp=false;
        posValidaDown=false;
        posValidaIzq=false;
        posValidaDer=false;
        String[] posicionesUp = obtenerArreglo(nombreFicha,arribaXML);
        String[] posicionesDown = obtenerArreglo(nombreFicha,abajoXML);
        String[] posicionesIzq = obtenerArreglo(nombreFicha,izquierdaXML);
        String[] posicionesDer = obtenerArreglo(nombreFicha,derechaXML);
        posicionesValidas.add(posicionesUp);
        posicionesValidas.add(posicionesDown);
        posicionesValidas.add(posicionesIzq);
        posicionesValidas.add(posicionesDer);
        try 
        {
            for(int indice=0;indice<posicionesValidas.size();indice++)
            {
                if(indice==0)         
                {
                    posValidaUp=validarSintaxis(posicionesValidas.get(indice),Matriz,fila+1,colum,false);
                    System.out.println("arriba: "+posValidaUp);
                }
                else if(indice==1){
                    posValidaDown=validarSintaxis(posicionesValidas.get(indice),Matriz,fila-1,colum,false);
                    System.out.println("abajo: "+posValidaDown);
                }
                else if(indice==2){
                    posValidaIzq=validarSintaxis(posicionesValidas.get(indice),Matriz,fila,colum-1,false);
                    System.out.println("izquierda: "+posValidaIzq);
                }
                else{
                    posValidaDer=validarSintaxis(posicionesValidas.get(indice),Matriz,fila,colum+1,false);
                    System.out.println("derecha: "+posValidaDer);
                }
            }
        }
	catch (NullPointerException npe) {}
        catch( ArrayIndexOutOfBoundsException e ) {}
        obtenerRequerimientos(nombreFicha,fila,colum);
        posicionesValidas.removeAllElements();
        return posValidaUp&&posValidaDown&&posValidaIzq&&posValidaDer;
    }
    
    /*
     * Metodo encargado de obtener los requerimientos de una determinada ficha, por el momento la unica ficha
     * que tiene requerimientos es el led(requiere el umbral) por lo que es la unica validacion sobre fichas,
     * los requerimientos se meten en un String[] ya que puede existir mas de un requerimiento para una ficha
     */
    public void obtenerRequerimientos(String nombreFicha, int fila, int colum) throws JDOMException
    {
        requerimientos = obtenerArreglo(nombreFicha,requerimientosXML);
        if(requerimientos[0].equalsIgnoreCase(""))
            cumpleRequerimientos=true;
        else
            if(nombreFicha.equalsIgnoreCase(led))
            {
                posFilaEspecial=fila;
                posColumEspecial=colum;
                System.out.println("");
                System.out.println("Para poder continuar debe agregar la(s) siguientes fichas:");
                for(int indice=0;indice < requerimientos.length;indice++)
                    System.out.println(requerimientos[indice]);
                System.out.println("");
            }
    }
    
   /*
     * Se encarga de analizar que los requerimientos del led sean correctos, para ello cuando se coloca el led 
     * se guarda la posicion de este, una vez que se coloca el umbral se analiza que entre la posicion guardada
     * de led y la posicione del umbral exista ya sea un tubo vertical o uno horizontal
     */
    public boolean analizarRequerimientosLed(String Matriz[][],int fila, int colum, String nombreFicha)
    {
        System.out.println("***AQUI LLEGO BIEN***");
        System.out.println("Fila especial: "+posFilaEspecial);
        System.out.println("Columna especial: "+posColumEspecial);
        System.out.println("Fila : "+fila);
        System.out.println("Columna: "+colum);
        System.out.println("*****************");
        // posFilaEspecial y posColumnaEspecial son las posiciones guardadas de led
        if(fila==posFilaEspecial) // si la fila es la misma lo que debe existir entre el led y el umbral es un tubo vertical
        {
            if(posColumEspecial<colum)
            {
                System.out.println("********");
                System.out.println(Matriz[fila][posColumEspecial+1]);
                System.out.println("********");
                if(Matriz[fila][posColumEspecial+1].equalsIgnoreCase(tuboVertical))
                    cumpleRequerimientos=true;
            }
            else
                if(Matriz[fila][posColumEspecial-1].equalsIgnoreCase(tuboVertical))
                    cumpleRequerimientos=true;
        }
        else if(colum==posColumEspecial ) // si la columna es la misma lo que debe existir entre el led y el umbral es un tubo horizontal
        {
            if(posFilaEspecial<fila)
            {
                if(Matriz[posFilaEspecial+1][colum].equalsIgnoreCase(tuboHorizontal))
                    cumpleRequerimientos=true;
            }
            else
                if(Matriz[posFilaEspecial-1][colum].equalsIgnoreCase(tuboHorizontal))
                    cumpleRequerimientos=true;
        }
        else
            cumpleRequerimientos=false;
        
        return cumpleRequerimientos;
    }
    
    public String[] ObtenerRequerimientosActuales()
    {
        return requerimientos;
    }
    
    public void eliminarRequerimientos()
    {
        requerimientos=stringNulo;
        cumpleRequerimientos=false;
    }
    
    /*
     * Se encarga de comprobar la sintaxis de una determinada ficha, para lo cual utilizando el vector obtenido
     * en el metodo validarSintaxisDePosicion analiza las posiciones vecinas de la ficha, una vez que llega a una 
     * posicion vecina por ejemplo arriba, analiza en el vector las fichas que se pueden colocar arriba, de estar
     * la posicion vecina entre esas o de estar vacia significa una correcta sintaxis, analiza para TODAS las 
     * posiciones vecinas
     */
    private boolean validarSintaxis(String[] arreglo,String Matriz[][],int fila,int colum,boolean valida)
    {
        try 
        {
            for(int indice=0;indice<arreglo.length;indice++)
            {
                if(arreglo[indice].equals(Matriz[fila][colum]) || Matriz[fila][colum].equalsIgnoreCase(casillaNula))
                {
                    valida=true;
                    break;
                }
            }
            
        }
        catch (NullPointerException npe) {}
        catch( ArrayIndexOutOfBoundsException e ) {}
        return valida;
    }
    
    /*
     * Utilizando Xpath obtiene el arreglo correspondiente a las posiciones correctas que puede tener
     * una ficha en alguna direccion(ej arriba)
     */
    private String[] obtenerArreglo(String pIdFicha,String pLado) throws JDOMException
    {
        NodoTem = (Element)XPath.selectSingleNode(documento, "/root/"+pIdFicha+"/"+pLado);
        if(NodoTem != null)
        {
            String arreglo[] = NodoTem.getText().split(",");
            return arreglo;
        }
        else
        {
            return null;
        }
    }
    
}
